﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using Spelprojekt.Model;

namespace Spelprojekt.View
{
    public class GameView : IGameView
    {
        Camera m_camera = new Camera();     
        GameAssets m_gameAssets = new GameAssets();
        ParticleSystem m_pSystem = new ParticleSystem();
        ParticleView m_pView = new ParticleView();                

        private SpriteEffects m_flip = SpriteEffects.FlipHorizontally;        

        public void Draw(Spelprojekt.Model.Game a_game, SpriteBatch spriteBatch, GameAssets a_assets, float a_elapsedTime)
        {
            m_camera.DoScroll(a_game.m_player.m_position);

            DrawBackground(a_game.m_map, spriteBatch, a_assets);
            DrawMap(a_game.m_map, spriteBatch, a_assets);            
            DrawPlayer(a_game.m_player, spriteBatch, a_assets);
            DrawEnemy(a_game, spriteBatch, a_assets);            
         
            //DrawTestText(a_game.m_map, spriteBatch, a_assets);                        
        }        

        private void DrawTestText(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();      

            spriteBatch.DrawString(a_assets.m_font, String.Format("{0}", m_camera.m_top), new Vector2(100.0f,.0f),Color.White);

            spriteBatch.DrawString(a_assets.m_font, String.Format("{0}", m_camera.m_left), new Vector2(100.0f, 20.0f), Color.White);

            spriteBatch.End();
        }

        public void DrawWin(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(a_assets.m_win, new Vector2(500.0f, 200.0f), Color.White);
     
            spriteBatch.End();
        }

        public void DrawDie(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(a_assets.m_died, new Vector2(500.0f, 200.0f), Color.White);

            spriteBatch.End();
        }

        public void DrawCleared(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(a_assets.m_cleared, new Vector2(500.0f, 200.0f), Color.White);

            spriteBatch.End();
        }

        public void DrawPaused(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(a_assets.m_paused, new Vector2(500.0f, 200.0f), Color.White);

            spriteBatch.End();
        }

        public void DrawLogo(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            spriteBatch.Draw(a_assets.m_logo, new Vector2(500.0f, 0.0f), Color.White);

            spriteBatch.End();
        }
        
        private void DrawBackground(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();

            Vector2 topLeft = m_camera.GetTopLeftPercent();

            int x = -(int)(topLeft.X * a_assets.m_background.Width);
            int y = -(int)(topLeft.Y * a_assets.m_background.Height);

            int width = (int)((a_assets.m_background.Width / (Model.Map.g_width * m_camera.m_scaleX)) * Camera.g_width);
            int height = (int)((a_assets.m_background.Height / (Model.Map.g_height * m_camera.m_scaleY)) * Camera.g_height);

            Rectangle sourceRectangle = new Rectangle(x, y, width, height);
            Rectangle screenRectangle = new Rectangle(0,0, Camera.g_width, Camera.g_height);

            spriteBatch.Draw(a_assets.m_background, screenRectangle, sourceRectangle, Color.White);

            spriteBatch.End();
        }

        private void DrawMap(Spelprojekt.Model.Map a_map, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();
            for (int x = 0; x < Map.g_width; x++)
            {
                for (int y = 0; y < Map.g_height; y++)
                {
                    //if the tile is a block
                    if (a_map.m_tiles[x, y].m_tileType == Tile.TileType.Blocked)
                    {                       
                        Vector2 position = new Vector2(x, y);
                        Vector2 visualPosition = m_camera.GetViewPos(position);

                        spriteBatch.Draw(a_assets.m_brick, visualPosition, Color.White);
                    }
                    
                    if (a_map.m_tiles[x, y].m_tileType == Tile.TileType.Exit)
                    {                        
                        Vector2 position = new Vector2(x, y);
                        Vector2 visualPosition = m_camera.GetViewPos(position);

                        spriteBatch.Draw(a_assets.m_exit, visualPosition, Color.White);
                    }

                    if (a_map.m_tiles[x, y].m_tileType == Tile.TileType.Deadly)
                    {
                        Vector2 position = new Vector2(x, y);
                        Vector2 visualPosition = m_camera.GetViewPos(position);

                        spriteBatch.Draw(a_assets.m_deadly, visualPosition, Color.White);
                    }   
                }
            }
            spriteBatch.End();
        }         

        private void DrawPlayer(Spelprojekt.Model.Player a_player, SpriteBatch spriteBatch, GameAssets a_assets)
        {            
            spriteBatch.Begin();            

            Rectangle playerRectangle = m_camera.GetPlayerViewRectangle(a_player.m_position, Player.m_size2);
            Rectangle screenRectangle = new Rectangle(0, 0, 200, 200);

            spriteBatch.Draw(a_assets.m_wizard, playerRectangle, screenRectangle, Color.White);            

            if (MasterController.g_isDebugging)
            {
                Vector2 vp = m_camera.GetViewPos(a_player.m_position);

                Player p = new Player();
                Rectangle destRect = new Rectangle( (int)(vp.X - m_camera.m_scaleX * p.m_size.X / 2.0f),
                                                    (int)(vp.Y - m_camera.m_scaleY * p.m_size.Y),
                                                    (int)(m_camera.m_scaleX * p.m_size.X),
                                                    (int)(m_camera.m_scaleY * p.m_size.Y));
                
                spriteBatch.Draw(a_assets.m_brick, destRect, Color.White);
            }

            spriteBatch.End();          
        }               

        private void DrawEnemy(Spelprojekt.Model.Game a_game, SpriteBatch spriteBatch, GameAssets a_assets)
        {
            spriteBatch.Begin();           
            
            foreach (Spelprojekt.Model.Enemy m_enemy in a_game.m_enemies)
            {                                                
                Rectangle enemyRectangle = m_camera.GetEnemyViewRectangle(m_enemy.m_position, Enemy.m_size2);
                Rectangle screenRectangle = new Rectangle(0, 0, 200, 200);                

                if (m_enemy.m_position.X < a_game.m_player.m_position.X)
                {
                    spriteBatch.Draw(a_assets.m_enemy, enemyRectangle, screenRectangle, Color.White);
                }
                else
                {
                    spriteBatch.Draw(a_assets.m_enemy, enemyRectangle, screenRectangle, Color.White, (float)0.0, new Vector2((float)0.0), this.m_flip, 0);
                }
                
                if (MasterController.g_isDebugging)
                {
                    Vector2 vp = m_camera.GetViewPos(m_enemy.m_position);

                    Enemy p = new Enemy();
                    Rectangle destRect = new Rectangle((int)(vp.X - m_camera.m_scaleX * p.m_size.X / 2.0f),
                                                        (int)(vp.Y - m_camera.m_scaleY * p.m_size.Y),
                                                        (int)(m_camera.m_scaleX * p.m_size.X),
                                                        (int)(m_camera.m_scaleY * p.m_size.Y));

                    spriteBatch.Draw(a_assets.m_brick, destRect, Color.White);
                }             

            }           

            spriteBatch.End();            
        }

        public void DrawParticles(Model.Game a_game, SpriteBatch spriteBatch, GameAssets a_assets, float a_elapsedTime)
        {
            m_pSystem.Update(a_elapsedTime);
            m_pView.Render(m_camera, m_pSystem, spriteBatch, a_assets);
        }

        public void OnDeath(Vector2 a_pos, Vector2 a_speed)
        {
            //number of particles
            int particles = ParticleSystem.m_random.Next(40, 60);

            for (int i = 0; i < particles; i++)
            {
                m_pSystem.CreateBloodSplatter(a_pos, a_speed);
            }
        }

        public void OnRunLeft(Vector2 a_pos, Vector2 a_speed)
        {
            //number of particles
            int particles = ParticleSystem.m_random.Next(50, 60);

            for (int i = 0; i < particles; i++)
            {
                m_pSystem.RunCloudLeft(a_pos, a_speed);
            }
        }

        public void OnRunRight(Vector2 a_pos, Vector2 a_speed)
        {
            //number of particles
            int particles = ParticleSystem.m_random.Next(50, 60);

            for (int i = 0; i < particles; i++)
            {
                m_pSystem.RunCloudRight(a_pos, a_speed);
            }
        }
    }
}
